<?php

namespace lib\Server;

use lib\Root;

class Server
{
	static public $swoole_instance  = null;
	static public $server_instances = [];
	static public $_config          = [];
	static public $_pid_file        = TMP_DIR . '__.pid';
	static public $_process_title = SERVER_SOFT_NAME;
	static public $_master_pid    = [];

	public function startReady()
	{
		$this->isCli();
		$this->initServer();
		$this->command();
		$this->startServers();
		$this->start();
	}

	public function startServers()
	{
		self::$_config = Root::Config('servers');

		foreach (self::$_config as $key => $service) {
			switch ($service['type']) {
				case 'http':
					(new TcpHttpServer())->start($service);
					break;
				case 'https':
					(new TcpHttpsServer())->start($service);
					break;
				case 'thrift':
					(new ThriftServer())->start($service);
					break;
			}
		}


	}

	public function start()
	{
		self::$swoole_instance->start();
	}


	public function isCli()
	{
		if (php_sapi_name() != "cli") {
			exit("only run in command line mode \n");
		}
	}

	/**
	 * 服务器启动之前的准备工作
	 */
	public function initServer()
	{
		if (empty(self::$_pid_file)) {
			self::$_pid_file = TMP_DIR . '__.pid';
		}
		TcpServer::setProcessTitle('SwCS_Service');
	}

	public function command()
	{
		global $argv;

		$start_file = $argv[0];

		if (!isset($argv[1])) {
			exit("Usage: php " . $start_file . "/bin/start.php {start|stop|reload|restart}\n");
		}

		if (file_exists(self::$_pid_file)) {
			$pids = explode(',', file_get_contents(self::$_pid_file));
			// Get master process PID.
			$master_pid      = $pids[0];
			$manager_pid     = $pids[1];
			$master_is_alive = $master_pid && @posix_kill($master_pid, 0); //检测进程是否存在
		}
		else {
			$master_is_alive = false;
		}

		$command = trim($argv[1]);

		if ($master_is_alive) {
			if ($command === 'start' || $command === 'test') {
				echo("system [$start_file] already running\n");
				exit;
			}
		}
		elseif ($command !== 'start' && $command !== 'test') {
			echo("system [$start_file] not run\n");
			exit;
		}

		switch ($command) {
			case 'start';
				break;
			case 'stop';
				@unlink(self::$_pid_file);
				echo("system [$start_file] is stoping ...\n");
				// Send stop signal to master process.
				$master_pid && posix_kill($master_pid, SIGTERM);
				// Timeout.
				$timeout    = 5;
				$start_time = time();
				// Check master process is still alive?
				while (1) {
					$master_is_alive = $master_pid && posix_kill($master_pid, 0);
					if ($master_is_alive) {
						// Timeout?
						if (time() - $start_time >= $timeout) {
							echo("system [$start_file] stop fail\n");
							exit;
						}
						// Waiting amoment.
						usleep(10000);
						continue;
					}
					// Stop success.
					echo("system [$start_file] stop success\n");
					break;
				}
				exit(0);
				break;
			case 'reload';
				posix_kill($manager_pid, SIGUSR1);
				echo("system [$start_file] reload\n");
				exit;
				break;
			case 'restart';
				@unlink(self::$_pid_file);
				echo("Swoole[$start_file] is stoping ...\n");
				// Send stop signal to master process.
				$master_pid && posix_kill($master_pid, SIGTERM);
				// Timeout.
				$timeout    = 5;
				$start_time = time();
				// Check master process is still alive?
				while (1) {
					$master_is_alive = $master_pid && posix_kill($master_pid, 0);
					if ($master_is_alive) {
						// Timeout?
						if (time() - $start_time >= $timeout) {
							echo("system [$start_file] stop fail\n");
							exit;
						}
						// Waiting amoment.
						usleep(10000);
						continue;
					}
					// Stop success.
					echo("system [$start_file] stop success\n");
					break;
				}
				break;
		}
	}

}